
#ifndef TOOLS_THREAD_MESSAGEQUEUE_HPP__
# define TOOLS_THREAD_MESSAGEQUEUE_HPP__

# include <deque>
# include <mutex>
# include <condition_variable>

namespace Tools {
    namespace Thread {
        template <typename T>
        class MessageQueue {
            public:
                MessageQueue() {}

                void send(T && message) {
                    {
                        std::lock_guard<std::mutex> lg(this->_mutex);
                        this->_queue.push_front(std::move(message));
                    }
                    this->_cond.notify_one();
                }

                T receive() {
                    std::unique_lock<std::mutex> ul(this->_mutex);
                    this->_cond.wait(ul, [this]{ return !this->_queue.empty(); });
                    T message = std::move(this->_queue.back());
                    this->_queue.pop_back();
                    return message;
                }

            private:
                std::deque<T> _queue;
                std::mutex _mutex;
                std::condition_variable _cond;
        };
    }
}

#endif // TOOLS_THREAD_MESSAGEQUEUE_HPP__
